<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            overflow: hidden;
        }

        #canvas {
            width: 100%;
            height: 100vh;
            /* background-color: rgba(255, 0, 0, 0.4); */
            position: fixed;
            top: 0px;
            left: 0px;
        }
    </style>
</head>

<body>
    <canvas id="canvas"></canvas>
</body>
<script id="ColorVS" type="x-shader/x-vertex">
    attribute vec4 a_Position;
    uniform float u_PointSize;
    uniform mat4 u_ModelM4;
    uniform mat4 u_PvM4;
    void main(){
        gl_Position = u_PvM4 * u_ModelM4 * a_Position;
        gl_PointSize = u_PointSize;
    }
</script>
<script id="ColorFS" type="x-shader/x-fragment">
    precision mediump float;
    uniform vec4 u_Color;
    void main(){
        gl_FragColor = u_Color;
    }
</script>
<script id="ImageVS" type="x-shader/x-vertex">
    attribute vec4 a_Position;
    attribute vec2 a_Pin;
    uniform mat4 u_ModelM4;
    uniform mat4 u_PvM4;
    varying vec2 v_Pin;
    void main(){
        gl_Position = u_PvM4 * u_ModelM4 * a_Position;
        gl_PointSize = 30.0;
        v_Pin = a_Pin;
    }
</script>
<script id="ImageFS" type="x-shader/x-fragment">
    precision mediump float;
    uniform sampler2D u_Sampler1;
    varying vec2 v_Pin;
    void main(){
        gl_FragColor = texture2D(u_Sampler1, v_Pin);
        //gl_FragColor = vec4(1.0,0.0,0.0,1.0);
    }
</script>
<script type="module">
    import { Matrix4, Vector3, Color, OrthographicCamera, PerspectiveCamera, Spherical } from '../js/three.module.js';
    import { CreateProgram, imgPromise } from '../js/Utils.js';
    import lib from '../js/ThreeLib.js';
    import CameraController from '../js/CameraController.js'
    import Poly from '../js/Poly4.js'
    import Control from '../js/Control.js'
    import Square from '../js/objs/Square.js'

    import Geo from '../js/Poly2/Geo.js'
    import Mat from '../js/Poly2/Mat.js'
    import Obj3D from '../js/Poly2/Obj3D.js'
    import Scene from '../js/Poly2/Scene.js'



    //#region gl
    const canvas = document.getElementById("canvas");
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    const gl = canvas.getContext("webgl", { antialias: true, });
    gl.enable(gl.BLEND);
    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
    gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);//去图片描边
    gl.enable(gl.DEPTH_TEST);
    //#endregion

    const scene = new Scene({ gl: gl });
    scene.regProgram('color', {
        program: CreateProgram(gl,
            document.querySelector('#ColorVS').innerText,
            document.querySelector('#ColorFS').innerText),
        attribs: ['a_Position'],
        uniforms: ['u_PvM4', 'u_ModelM4', 'u_PointSize', 'u_Color']
    })
    scene.regProgram('image', {
        program: CreateProgram(gl,
            document.querySelector('#ImageVS').innerText,
            document.querySelector('#ImageFS').innerText),
        attribs: ['a_Position', 'a_Pin'],
        uniforms: ['u_PvM4', 'u_ModelM4', 'u_Sampler1']
    })


    const pvM4 = new Matrix4();
    const modelM4 = new Matrix4();
    const eye = new Vector3(0, 0, 3);
    const lookAt = new Vector3();





    function setPvM41(eye, lookAt) {
        const eyem = new Matrix4().setPosition(eye.x, eye.y, eye.z);
        const lookAtm = new Matrix4().lookAt(
            eye, lookAt, new Vector3(0, 1, 0)
        );
        const viewm = (eyem.multiply(lookAtm)).invert();

        const viewH = 1;//设定视图矩阵高度  
        const wh = canvas.width / canvas.height;
        const viewW = viewH * wh;//求视图矩阵宽度  
        const [l, r, t, b, q, h] = [
            -viewW, viewW, viewH, -viewH, 1, 20
        ];
        const projectionm = new Matrix4().makeOrthographic(l, r, t, b, q, h);

        pvM4.copy(projectionm.multiply(viewm));
    }

    setPvM41(eye, lookAt);



    //#region main



    let obj01;

    const image = new Image();
    image.src = '../Image/Image02.jpg';
    image.onload = function () {


        const wh = image.width / image.height;
        const [w, h] = [wh, 1];

        const geo = new Geo({
            data: {
                'a_Position': {
                    size: 3, array: new Float32Array(
                        [
                            -w, h, 0,
                            -w, -h, 0,
                            w, -h, 0,
                            w, h, 0
                        ]
                    )
                },
                'a_Pin': {
                    size: 2, array: new Float32Array(
                        [
                            0, 1, 0, 0, 1, 0, 1, 1,
                        ]
                    )
                }
            },
            element: { array: new Uint16Array([0, 1, 2, 0, 2, 3]) }
        });
        const mat = new Mat({
            program: 'image',
            mode: ['TRIANGLES', 'POINTS'],
            data: {
                'u_PvM4': { type: 'uniformMatrix4fv', value: pvM4.elements },
                'u_ModelM4': { type: 'uniformMatrix4fv', value: modelM4.elements },
            },
        });


        //创建
        mat.maps = {
            'u_Sampler1': {
                image: image,
                WRAP_W: gl.CLAMP_TO_EDGE,
                WRAP_H: gl.CLAMP_TO_EDGE,
                MIN_FILTER: gl.LINEAR,
            },
        };

        obj01 = new Obj3D({ geo: geo, mat: mat })
        scene.add(obj01);


        window.onresize = function () {
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;
            setPvM41(eye, lookAt);
            gl.viewport(0, 0, canvas.width, canvas.height);

            let [w, h] = [wh, 1];

            let [cw, ch] = [canvas.width / canvas.height, 1];
            if (cw > w) {
                w = cw;
                h = 1 * (cw / wh);
            }

            console.log(w, h)
            obj01.setAttrib('a_Position', {
                array: new Float32Array(
                    [
                        -w, h, 0,
                        -w, -h, 0,
                        w, -h, 0,
                        w, h, 0
                    ]
                )
            })
        }

        console.log(w, h)
        console.log(canvas.width / canvas.height, 1)

    };

    //#endregion



    (function ani() {
        draw();
        requestAnimationFrame(ani)

        // console.log(obj01.geo.data['a_Position'].array)
    })();




    function create(vertices, elements = null, color = [Math.random(), Math.random(), Math.random(), 1]) {
        const geo = new Geo({
            data: {
                'a_Position': { size: 3, array: new Float32Array(vertices) },
            }
        });
        const mat = new Mat({
            program: 'color',
            mode: ['LINES', 'POINTS'],
            data: {
                'u_PvM4': { type: 'uniformMatrix4fv', value: pvM4.elements },
                'u_ModelM4': { type: 'uniformMatrix4fv', value: modelM4.elements },
                'u_PointSize': { type: 'uniform1f', value: 30 },
                'u_Color': { type: 'uniform4fv', value: color },
            },
        });
        if (elements != null) {
            geo.element = { array: new Uint16Array(elements) };
            mat.mode = ['TRIANGLES'];
        }
        return new Obj3D({ geo: geo, mat: mat, });
    }

    function draw() {
        scene.setUniform('u_PvM4', { value: pvM4.elements });
        scene.draw();
    }
</script>

</html>